package com.laguille.games.tetris.model;

import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.concurrent.locks.Lock;

import com.laguille.games.tetris.model.Tetromino.Direction;
import com.laguille.games.tetris.model.Tetromino.TetrominoBlock;
import com.laguille.games.tetris.model.Tetromino.TetrominoPiece;
import com.laguille.games.tetris.model.Tetromino.impl.IPiece;
import com.laguille.games.tetris.model.Tetromino.impl.JPiece;
import com.laguille.games.tetris.model.Tetromino.impl.LPiece;
import com.laguille.games.tetris.model.Tetromino.impl.OPiece;
import com.laguille.games.tetris.model.Tetromino.impl.SPiece;
import com.laguille.games.tetris.model.Tetromino.impl.TPiece;
import com.laguille.games.tetris.model.Tetromino.impl.ZPiece;

public class Model {
	private Field field;
	
	public Model() 
	{
		field = new Field();
		currentPiece = generateRandomPiece();
		generateNextPiece();
		field.addPiece(currentPiece);
	}
	
	public void nextStep()
	{
		if (!field.movePiece(currentPiece, Direction.DOWN))
		{
			List<Integer> lineNumbers = field.getFullLines();
			if (!lineNumbers.isEmpty())
			{
				field.removeLines(lineNumbers.toArray(new Integer[0]));
				field.shiftLinesDown(Collections.max(lineNumbers), lineNumbers.size());
				System.out.println("\nafter:\n" + field);
			}

			currentPiece = nextPiece;
			if (!field.addPiece(currentPiece))
			{
				System.out.println("Game over...");
				System.exit(1);
			}
			generateNextPiece();
		}
	}
	
	private TetrominoPiece currentPiece, nextPiece;
	
	public TetrominoPiece getCurrentPiece() 
	{
		return currentPiece;
	}

	public TetrominoPiece getNextPiece() 
	{
		return nextPiece;
	}
	
	public void generateNextPiece() 
	{
		nextPiece = generateRandomPiece();
	}
	
	private TetrominoPiece generateRandomPiece() 
	{
		TetrominoPiece piece = null;
		
		Random random = new Random(System.currentTimeMillis());
		int randInt = random.nextInt(7);
		switch (randInt) 
		{
			case 0 : 
				piece = new IPiece();
				break;
			case 1 :
				piece = new JPiece();
				break;
			case 2 : 
				piece = new LPiece();
				break;
			case 3 :
				piece = new OPiece();
				break;
			case 4 : 
				piece = new SPiece();
				break;
			case 5 :
				piece = new TPiece();
				break;
			case 6 :
				piece = new ZPiece();
				break;
			default :
				assert false;
		}
		return piece;
	}

	public Field getField() {
		return field;
	}
	
}
